Univalle


Análisis de Series de Tiempo y Pronósticos ARIMA

Estudio Empírico sobre el Precio de Acciones de Tesla Inc.


1. Introducción

1.1 Relevancia del Análisis

1.2 Metodología: Modelos ARIMA


2. Descripción de la Serie Temporal

2.1 serie QQQ historica

library(tidyquant)
library(tidyverse)
library(ggplot2)
library(zoo)
library(plotly)

serie <- getSymbols('QQQ', src='yahoo', auto.assign=FALSE, from="2010-01-01")
precios <- serie$QQQ.Close
datos_qqq <- data.frame(
  Fecha = index(precios),
  Precio = as.numeric(precios)
)
datos_qqq <- datos_qqq %>%
  mutate(Corte = as.yearqtr(Fecha)) 
lista_frames <- lapply(unique(datos_qqq$Corte), function(c) {
  dt <- datos_qqq[datos_qqq$Corte <= c, ]
  dt$Frame <- as.character(c) 
  return(dt)
})

datos_animados <- dplyr::bind_rows(lista_frames)
p <- ggplot(datos_animados, aes(x = Fecha, y = Precio)) +
  
  geom_area(aes(frame = Frame), fill = tesla_pal$primary, alpha = 0.1, position = "identity") +
  
  geom_line(aes(frame = Frame), color = tesla_pal$primary, size = 0.8) +
  
  labs(
    title = "Evolución Dinámica del QQQ",
    subtitle = "Crecimiento histórico acumulado",
    x = "", 
    y = "Precio (USD)"
  ) +
  scale_y_continuous(labels = scales::dollar_format()) +
  theme_tesla() +
  theme(plot.title = element_text(size = 14))

plotly::ggplotly(p, tooltip = c("x", "y")) %>%
  plotly::layout(
    paper_bgcolor = 'rgba(0,0,0,0)',
    plot_bgcolor = 'rgba(0,0,0,0)',
    font = list(family = "Inter, sans-serif", color = tesla_pal$text_gray),
    hovermode = "x unified"
  ) %>%
  plotly::animation_opts(
    frame = 100,       
    transition = 0,    
    redraw = FALSE     
  ) %>%
  plotly::animation_slider(
    currentvalue = list(prefix = "Periodo: ") 
  ) %>%
  plotly::config(displayModeBar = FALSE)

2.2 División sectorial

library(plotly)
sectores <- data.frame(
  Sector = c("Tecnología", "Consumo Discrecional", "Servicios de Comunicación", 
             "Consumo Básico", "Industriales", "Salud", "Otros", 
             "Servicios Públicos", "Materiales", "Energía"),
  Peso = c(53.60, 13.04, 12.61, 4.99, 4.58, 4.28, 3.22, 1.38, 1.25, 0.47)
)

colores_sector <- c(
  "#2b5c8a",
  "#5d5b94", 
  "#8e6fa3",
  "#c46d9e",
  "#e67586", 
  "#f38972", 
  "#f8a262",
  "#fbc058", 
  "#fce05d", 
  "#34495e"  
)
fig_pie <- plot_ly(sectores, labels = ~Sector, values = ~Peso, type = 'pie',
        textposition = 'outside',      
        textinfo = 'label+percent',    
        hoverinfo = 'label+value+percent',
        marker = list(
          colors = colores_sector, 
          line = list(color = '#ffffff', width = 1.5) 
        ),
        sort = FALSE, 
        automargin = TRUE
)

fig_pie <- fig_pie %>% layout(
  title = list(
    text = "<b>Asignación Sectorial</b>",
    font = list(size = 22, family = "Poppins, sans-serif", color = tesla_pal$text_main),
    x = 0.05, 
    y = 0.95
  ),
  showlegend = FALSE, 
  margin = list(t = 80, b = 40, l = 80, r = 80), 
  paper_bgcolor = 'rgba(0,0,0,0)',
  plot_bgcolor = 'rgba(0,0,0,0)',
  font = list(family = "Inter, sans-serif", size = 12, color = tesla_pal$text_gray)
)

fig_pie

2.3 Mayores Holdings

library(packcircles)
library(dplyr)
library(ggplot2)
library(plotly)

top10 <- data.frame(
  ticker = c("NVDA","AAPL","MSFT","AVGO","AMZN","GOOGL","GOOG","TSLA","META","NFLX"),
  empresa = c("NVIDIA","Apple Inc.","Microsoft","Broadcom Inc.","Amazon.com, Inc.",
              "Alphabet Class A","Alphabet Class C","Tesla, Inc.","Meta Plataformas, Inc.","Netflix, Inc."),
  peso = c(9.33, 8.78, 7.69, 6.59, 5.21, 3.97, 3.71, 3.31, 2.93, 2.36),
  sector = c("Tecnología","Tecnología","Tecnología","Tecnología",
             "Consumo","Comunicación","Comunicación",
             "Consumo","Comunicación","Consumo"),
  stringsAsFactors = FALSE
)

otros_val <- round(100 - sum(top10$peso), 2)
holdings <- bind_rows(top10,
                      data.frame(ticker="OTROS", empresa="Resto del QQQ",
                                 peso = otros_val, sector="Varios", stringsAsFactors = FALSE)) %>%
  arrange(desc(peso))

packing <- circleProgressiveLayout(holdings$peso, sizetype='area')
holdings_pack <- cbind(holdings, packing)
holdings_pack$id <- seq_len(nrow(holdings_pack))
holdings_pack <- holdings_pack %>% rename(center_x = x, center_y = y)

dat.gg <- circleLayoutVertices(packing, npoints = 100)
dat.gg <- merge(dat.gg, holdings_pack, by = "id")

holdings_pack <- holdings_pack %>%
  mutate(
    peso_label = gsub("\\.", ",", formatC(peso, digits = 2, format = "f")),
    hover_text = paste0(
      empresa, "\n",
      "Ticker: ", ticker, "\n",
      "Peso: ", peso_label, "%\n",
      "Sector: ", sector
    ),
    label_text = ifelse(peso >= 2.3, paste0(ticker, "\n", peso_label, "%"), "")
  )

fill_map <- c(
  "Tecnología"   = tesla_pal$primary,
  "Consumo"      = tesla_pal$secondary,
  "Comunicación" = "#3b82f6",
  "Varios"       = tesla_pal$text_gray
)

p_bubble <- ggplot() +
  geom_polygon(
    data = dat.gg,
    aes(x = x, y = y, group = id, fill = sector,
        text = holdings_pack$hover_text[match(id, holdings_pack$id)]),
    color = "white", size = 0.5, alpha = 0.95
  ) +
  geom_text(
    data = holdings_pack,
    aes(x = center_x, y = center_y, label = label_text, text = hover_text),
    size = 3.8, color = "white", fontface = "bold", lineheight = 0.9
  ) +
  scale_fill_manual(values = fill_map) +
  theme_void() +
  coord_equal() +
  labs(title = "Composición del Portafolio QQQ",
       subtitle = "Top holdings según la imagen") +
  theme(
    plot.title = element_text(face = "bold", size = 16, color = tesla_pal$text_main, hjust = 0.5),
    plot.subtitle = element_text(size = 12, color = tesla_pal$text_gray, hjust = 0.5),
    legend.position = "bottom",
    legend.title = element_blank(),
    plot.margin = margin(10,10,10,10)
  )

ggplotly(p_bubble, tooltip = "text") %>%
  config(displayModeBar = FALSE) %>%
  layout(
    font = list(family = "Inter", color = tesla_pal$text_main),
    plot_bgcolor  = "rgba(0,0,0,0)",
    paper_bgcolor = "rgba(0,0,0,0)",
    legend = list(orientation = "h", yanchor = "bottom", y = -0.12, xanchor = "center", x = 0.5),
    hoverlabel = list(
      bgcolor = "rgba(255,255,255,0.97)",
      bordercolor = "rgba(0,0,0,0.08)",
      font = list(family = "Inter", color = tesla_pal$text_main, size = 11)
    )
  )

2.4 Análisis Estadístico

library(moments)
library(knitr)

serie_vec <- as.numeric(serie)
valores_calculados <- c(
    length(serie_vec),
    mean(serie_vec, na.rm = TRUE),
    median(serie_vec, na.rm = TRUE),
    min(serie_vec, na.rm = TRUE),
    max(serie_vec, na.rm = TRUE),
    max(serie_vec, na.rm = TRUE) - min(serie_vec, na.rm = TRUE),
    var(serie_vec, na.rm = TRUE),
    sd(serie_vec, na.rm = TRUE),
    skewness(serie_vec, na.rm = TRUE),
    kurtosis(serie_vec, na.rm = TRUE)
)

desc <- data.frame(
  Métrica = c(
    "Observaciones Totales",
    "Media",
    "Mediana",
    "Mínimo",
    "Máximo",
    "Rango",
    "Varianza",
    "Desviación Estándar",
    "Asimetría (Skewness)",
    "Curtosis"
  ),
  Valor = format(valores_calculados, scientific = FALSE, big.mark = ",", digits = 2, nsmall = 2)
)

kable(
  desc,
  format = "html",
  align = c('l', 'r'),
  table.attr = "class='table' style='width:60%; margin:auto; font-size:18px;'"
)
Métrica Valor
Observaciones Totales 24,030.00
Media 7,570,967.37
Mediana 185.95
Mínimo 37.09
Máximo 288,200,400.00
Rango 288,200,362.91
Varianza 397,433,948,262,821.69
Desviación Estándar 19,935,745.49
Asimetría (Skewness) 3.46
Curtosis 19.67

2.5 Rendimientos Diarios

library(quantmod)
library(dplyr)
library(ggplot2)
library(tidyverse)
library(knitr)
precios <- serie$QQQ.Close
ret_diario  <- dailyReturn(precios, type = "log")
ret_mensual <- monthlyReturn(precios, type = "log")
ret_anual   <- yearlyReturn(precios, type = "log")
vol_anual <- sd(ret_diario) * sqrt(252)
resumen <- data.frame(
  Concepto = "Volatilidad Anualizada (Riesgo)",
  Valor = scales::percent(vol_anual, accuracy = 0.01)
)
kable(resumen, 
      format = "html", 
      table.attr = "class='table' style='width:50%; margin:auto;'")
Concepto Valor
Volatilidad Anualizada (Riesgo) 20.71%

2.6 Retornos Diarios

ret_df <- data.frame(Retorno = as.numeric(ret_diario))

ggplot(ret_df, aes(x = Retorno)) +
  geom_histogram(aes(y = ..density..), bins = 60, fill = tesla_pal$primary, alpha = 0.4) +
  geom_density(color = tesla_pal$secondary, size = 1.2) +
  labs(title = "Distribución de los Rendimientos Diarios del QQQ",
       x = "Retorno Diario (log)", y = "Densidad") +
  theme_tesla()

ret_anual_df <- data.frame(
  Fecha = index(ret_diario),
  Ret = as.numeric(ret_diario),
  Año = format(index(ret_diario), "%Y")
)

ggplot(ret_anual_df, aes(x = Año, y = Ret, group = Año)) +
  geom_boxplot(fill = tesla_pal$primary, alpha = 0.7) +
  labs(title = "Distribución de los Retornos Diarios por Año (QQQ)",
       x = "Año", y = "Retorno Diario") +
  theme_tesla() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))

2.7 Rendimientos por año

library(dplyr)
library(ggplot2)
library(lubridate)
ret_anual_df <- data.frame(
  Año = year(index(ret_anual)),
  Retorno = round(100 * as.numeric(ret_anual), 2)
)

ggplot(ret_anual_df, aes(x = factor(Año), y = Retorno)) +
  geom_col(fill = tesla_pal$primary) +
  geom_text(
    aes(label = paste0(Retorno, "%")),
    vjust = -0.5,
    color = tesla_pal$text_main,  
    size = 4
  ) +
  labs(title = "Retorno Anual del QQQ",
       x = "Año", y = "Retorno (%)") +
  theme_tesla()

2.8 Drawdown

library(PerformanceAnalytics)
library(ggplot2)
library(dplyr)
ret_diario <- dailyReturn(precios, type = "log")

dd <- PerformanceAnalytics::Drawdowns(ret_diario)
dd_df <- data.frame(
  Fecha = index(dd),
  Drawdown = as.numeric(dd)
)
ggplot(dd_df, aes(x = Fecha, y = Drawdown)) +
  geom_line(color = tesla_pal$primary, linewidth = 0.7) +
  labs(title = "Drawdown Histórico del QQQ",
       x = "", y = "Drawdown") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  theme_tesla()

2.9 Métricas Financieras

library(PerformanceAnalytics)
library(xts)

cagr <- Return.annualized(ret_diario, scale = 252)
cumulative_return <- Return.cumulative(ret_diario)

sharpe_annual <- (mean(ret_diario, na.rm=TRUE) / sd(ret_diario, na.rm=TRUE)) * sqrt(252)
sortino <- SortinoRatio(ret_diario, MAR = 0)
max_dd <- maxDrawdown(ret_diario)

calmar <- as.numeric(cagr) / abs(as.numeric(max_dd))

metrics <- data.frame(
  Métrica = c("CAGR (anual)", "Retorno acumulado", "Sharpe (aprx anual)", 
              "Sortino", "Max Drawdown", "Calmar"),
  Valor = c(
    scales::percent(as.numeric(cagr), accuracy = 0.01),
    scales::percent(as.numeric(cumulative_return), accuracy = 0.01),
    round(as.numeric(sharpe_annual), 3),
    round(as.numeric(sortino), 3),
    scales::percent(as.numeric(max_dd), accuracy = 0.1),
    round(as.numeric(calmar), 3)
  ),
  stringsAsFactors = FALSE
)

knitr::kable(metrics, format = "html", table.attr = "class='table' style='width:60%; margin:auto;'")
Métrica Valor
CAGR (anual) 15.25%
Retorno acumulado 853.64%
Sharpe (aprx anual) 0.789
Sortino 0.07
Max Drawdown 39.0%
Calmar 0.391
library(zoo)

rollsd30  <- rollapply(as.numeric(ret_diario), width = 30, FUN = sd, fill = NA, align = "right")
rollsd90  <- rollapply(as.numeric(ret_diario), width = 90, FUN = sd, fill = NA, align = "right")
rollsd252 <- rollapply(as.numeric(ret_diario), width = 252, FUN = sd, fill = NA, align = "right")

df_roll <- data.frame(
  Fecha = index(ret_diario),
  vol30 = rollsd30 * sqrt(252),
  vol90 = rollsd90 * sqrt(252),
  vol252 = rollsd252 * sqrt(252)
)

library(reshape2)
dfm <- melt(df_roll, id.vars = "Fecha", variable.name = "Window", value.name = "VolAnual")

ggplot(dfm, aes(x = Fecha, y = VolAnual, color = Window)) +
  geom_line(size = 0.8) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
  labs(title = "Volatilidad Rolling (annualizada)", y = "Vol Annualizada", x = "") +
  scale_color_manual(values = c("vol30" = tesla_pal$primary, "vol90" = tesla_pal$secondary, "vol252" = tesla_pal$text_gray)) +
  theme_tesla()

3 Estacionalidad Mensual del QQQ (2010–2025)

library(ggplot2)
library(viridis)

df_m <- data.frame(Fecha = index(ret_mensual), Ret = as.numeric(ret_mensual))
df_m <- df_m %>% mutate(Año = lubridate::year(Fecha), Mes = lubridate::month(Fecha, label = TRUE, abbr = TRUE), RetP = Ret*100)
tabla_m <- df_m %>% group_by(Año, Mes) %>% summarise(RetP = mean(RetP, na.rm = TRUE))
ggplot(tabla_m, aes(x = Mes, y = factor(Año), fill = RetP)) +
  geom_tile(color = "white") +
  scale_fill_viridis_c(option = "C", direction = 1, name = "Ret (%)") +
  labs(title = "Heatmap Estacional Mensual (QQQ)") +
  theme_tesla()

3.1 Resumen anual

library(dplyr)
library(tidyr)

df_ann <- data.frame(Fecha = index(ret_anual), Ret = as.numeric(ret_anual))
df_ann <- df_ann %>% mutate(Año = lubridate::year(Fecha), RetPct = Ret * 100)
vol_year <- ret_diario %>% 
  data.frame(Fecha = index(ret_diario), Ret = as.numeric(ret_diario)) %>%
  mutate(Año = lubridate::year(Fecha)) %>%
  group_by(Año) %>%
  summarise(Vol = sd(Ret, na.rm=TRUE)*sqrt(252)*100, Ret = sum(Ret)*100)
dd_df <- data.frame(Fecha = index(ret_diario), Ret = as.numeric(ret_diario))
dd_df <- dd_df %>% mutate(Año = lubridate::year(Fecha))
maxdd_yr <- dd_df %>% group_by(Año) %>%
  summarise(MaxDD = min( cumprod(1+Ret) / cummax(cumprod(1+Ret)) - 1 ) * 100)

res_yr <- left_join(vol_year, maxdd_yr, by = "Año") %>% arrange(desc(Año))
knitr::kable(res_yr, format = "html")
Año Vol Ret MaxDD
2025 24.01085 19.8561265 -23.495928
2024 18.03302 22.1833893 -13.848830
2023 17.82608 43.0437333 -11.281539
2022 32.16924 -40.1526683 -38.496874
2021 18.23745 23.7510479 -11.096463
2020 35.88099 38.9105082 -30.538843
2019 16.21407 32.0820049 -11.151713
2018 22.98643 -0.9676871 -24.100861
2017 10.34418 27.3572128 -5.247865
2016 16.25143 5.7496103 -12.408901
2015 17.94332 8.0094863 -14.184709
2014 13.85775 16.0271077 -8.602610
2013 12.25804 30.0496925 -6.252029
2012 15.35379 15.4073838 -12.048104
2011 23.75081 2.4844922 -16.809360
2010 19.26350 15.9736109 -16.654913
library(ggplot2)
library(dplyr)
library(xts)

datos_plot <- data.frame(
  Fecha = index(precios),
  Precio = as.numeric(precios)
)

fecha_corte <- as.Date("2022-10-07")  
fecha_chatgpt <- as.Date("2022-11-30") 

ggplot(datos_plot, aes(x = Fecha, y = Precio)) +
  geom_line(color = tesla_pal$text_gray, alpha = 0.5, size = 0.5) +
    geom_line(data = subset(datos_plot, Fecha >= fecha_corte), 
            aes(x = Fecha, y = Precio), 
            color = tesla_pal$primary, size = 1.2) +
  
  geom_vline(xintercept = as.numeric(fecha_chatgpt), 
             color = "#8e44ad", linetype = "dashed", size = 0.9) +

  annotate("text", x = fecha_chatgpt, y = 320, 
           label = "Lanzamiento\nChatGPT", 
           angle = 90, vjust = -0.8, color = "#8e44ad", fontface="bold") +
  
  labs(
    title = "Impacto del Lanzamiento de ChatGPT",
    subtitle = "El inicio de la tendencia alcista coincide con la aparición de la IA Generativa",
    x = "", y = "Precio QQQ"
  ) +
  theme_tesla()

library(ggplot2)
library(dplyr)
library(lubridate)
library(ggrepel) 
data_cronologia <- data.frame(
  Hito = c(
    "ChatGPT (OpenAI)", 
    "DALL·E 2", "Midjourney v3", "Stable Diffusion", 
    "Nuevo Bing", "Claude (Anthropic)", "GPT-4", "Copilot 365", 
    "Google I/O (AI)", "Llama 2", "Mistral 7B", "DALL·E 3", 
    "Gemini 1.0/Ultra", "Sora (Video)", "Gemini Android", 
    "Claude 3", "Llama 3", "GPT-4o", "PCs Copilot+"
  ),
  Fecha = as.Date(c(
    "2022-11-30", 
    "2022-04-06", "2022-07-25", "2022-08-22", 
    "2023-02-07", "2023-03-14", "2023-03-14", "2023-03-16", 
    "2023-05-10", "2023-07-18", "2023-09-27", "2023-10-19", 
    "2023-12-06", "2024-02-15", "2024-02-08", 
    "2024-03-04", "2024-04-18", "2024-05-13", "2024-05-20"  
  )),
  Categoria = factor(c(
    "EL PUNTO DE INFLEXIÓN",
    rep("🎨 IMAGEN Y VIDEO", 3),
    "🔄 INTEGRACIÓN", "📝 TEXTO Y LLMs", "📝 TEXTO Y LLMs", "🔄 INTEGRACIÓN",
    "🔄 INTEGRACIÓN", "📝 TEXTO Y LLMs", "📝 TEXTO Y LLMs", "🎨 IMAGEN Y VIDEO",
    "📝 TEXTO Y LLMs", "🎨 IMAGEN Y VIDEO", "🔄 INTEGRACIÓN",
    "📝 TEXTO Y LLMs", "📝 TEXTO Y LLMs", "📝 TEXTO Y LLMs", "🔄 INTEGRACIÓN"
  ), levels = c("EL PUNTO DE INFLEXIÓN", "📝 TEXTO Y LLMs", "🎨 IMAGEN Y VIDEO", "🔄 INTEGRACIÓN")),
  
  Importancia = c(
    "Critico", 
    "Normal", "Normal", "Normal", 
    "Critico", "Normal", "Critico", "Normal",
    "Normal", "Normal", "Normal", "Normal",
    "Critico", "Critico", "Normal",
    "Normal", "Normal", "Critico", "Normal"
  )
)

colores_cat <- c(
  "EL PUNTO DE INFLEXIÓN" = "#e17055", 
  "📝 TEXTO Y LLMs"       = "#00b894", 
  "🎨 IMAGEN Y VIDEO"     = "#06b6d4", 
  "🔄 INTEGRACIÓN"        = "#a29bfe"  
)

ggplot(data_cronologia, aes(x = Fecha, y = Categoria, color = Categoria)) +
  geom_line(aes(group = Categoria), size = 1, alpha = 0.3) +
  geom_point(aes(size = Importancia), alpha = 0.9) +
  geom_text_repel(
    aes(label = Hito), 
    size = 3.5, 
    fontface = "bold", 
    box.padding = 0.5,
    point.padding = 0.3,
    force = 2,
    direction = "y",      
    nudge_y = 0.2,        
    segment.color = "grey80"
  ) +
  scale_size_manual(values = c("Critico" = 5, "Normal" = 3), guide = "none") +
  scale_color_manual(values = colores_cat) +
  scale_x_date(date_breaks = "4 months", date_labels = "%b %Y") +
  geom_vline(xintercept = as.Date("2022-10-07"), linetype="dashed", color="#636e72") +
  annotate("text", x = as.Date("2022-10-07"), y = 4.3, label = "Inicio", 
           angle = 90, vjust = -0.5, size = 3, color="#636e72") +
  labs(
    title = "Cronología del Boom de la IA Generativa",
    subtitle = "Lanzamientos clave que definieron la tendencia (2022-2024)",
    x = "", y = ""
  ) +
  theme_tesla() +
  theme(
    legend.position = "none",
    axis.text.y = element_text(face = "bold", size = 10),
    panel.grid.major.y = element_line(linetype = "dotted") 
  )

library(tidyquant)
library(tidyverse)
library(plotly)

# Definimos la paleta por si no estaba cargada previamente
tesla_pal <- list(
  primary = "#cc0000",
  secondary = "#000000",
  text_main = "#333333",
  text_gray = "#666666"
)

# Definición de tema personalizado (theme_tesla) por si falta
theme_tesla <- function() {
  theme_minimal(base_family = "Inter") +
    theme(
      plot.title = element_text(face = "bold", size = 16, color = tesla_pal$text_main),
      plot.subtitle = element_text(size = 11, color = tesla_pal$text_gray, margin = margin(b = 15)),
      legend.position = "none",
      panel.grid.minor = element_blank(),
      panel.grid.major.x = element_blank(),
      panel.grid.major.y = element_line(color = "#e5e5e5", linetype = "dashed"),
      axis.text = element_text(color = tesla_pal$text_gray),
      axis.title = element_text(color = tesla_pal$text_gray, size = 10)
    )
}

# --- INICIO DEL CÓDIGO DEL GRÁFICO ---

tickers <- c("QQQ", "SPY", "DIA", "IWM")
nombres_map <- c(
  "QQQ" = "QQQ (Nasdaq-100)",
  "SPY" = "SPY (S&P 500)",
  "DIA" = "DIA (Dow Jones)",
  "IWM" = "IWM (Small Caps)"
)

# Descarga de datos
datos_comp <- tq_get(tickers, get = "stock.prices", from = "2010-01-01")

# Normalización
datos_norm <- datos_comp %>%
  group_by(symbol) %>%
  mutate(
    Retorno_Acum = (adjusted / first(adjusted)) - 1,
    Nombre = nombres_map[symbol]
  ) %>%
  ungroup()

colores_comp <- c(
  "QQQ" = tesla_pal$primary,   
  "SPY" = "#2c3e50",           
  "DIA" = "#7f8c8d",        
  "IWM" = "#f39c12"            
)

p_comp <- ggplot(datos_norm, aes(x = date, y = Retorno_Acum, color = symbol)) +
  geom_line(aes(size = symbol, alpha = symbol)) +
  
  scale_color_manual(values = colores_comp, labels = nombres_map) +
  scale_size_manual(values = c("QQQ" = 1.2, "SPY" = 0.6, "DIA" = 0.6, "IWM" = 0.6), guide="none") +
  scale_alpha_manual(values = c("QQQ" = 1, "SPY" = 0.7, "DIA" = 0.7, "IWM" = 0.6), guide="none") +
  
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  
  labs(
    title = "QQQ vs El Mercado",
    subtitle = "Rendimiento acumulado comparativo (2010 - Presente)",
    x = "",
    y = "Retorno Acumulado"
  ) +
  theme_tesla()

plotly::ggplotly(p_comp, tooltip = c("x", "y", "colour")) %>%
  layout(
    legend = list(
      orientation = "h", 
      x = 0.5, 
      xanchor = "center",
      y = 1.05,
      title = list(text = "")
    ),
    hovermode = "x unified"
  ) %>%
  config(displayModeBar = FALSE)

3. Resultados del Modelo ARIMA

3.1 Evaluación de Estacionariedad

[PLACEHOLDER: Documenta pruebas de estacionariedad KPSS y ADF. Interpreta resultados]

3.2 Análisis ACF y PACF

[PLACEHOLDER: Inserta gráficos ACF y PACF. Analiza patrones de autocorrelación]

library(ggplot2)
ggtsdisplay(diff(datos_tesla$Close))

3.3 Selección del Modelo

[PLACEHOLDER: Documenta parámetros p, d, q seleccionados y justificación]

Parámetro Valor Justificación
p [ ] [Basado en PACF]
d [ ] [Basado en tests de estacionariedad]
q [ ] [Basado en ACF]

3.4 Ajuste del Modelo

[PLACEHOLDER: Resumen del modelo ARIMA ajustado con coeficientes interpretados]

3.5 Diagnóstico de Residuos

[PLACEHOLDER: Análisis de residuos: gráficos, pruebas de normalidad y autocorrelación]

checkresiduals(fit)

3.6 Pronósticos

[PLACEHOLDER: Pronósticos para períodos futuros con intervalos de confianza]

forecast_tesla <- forecast(fit, h=10)
autoplot(forecast_tesla)

4. Conclusiones

4.1 Hallazgos Principales

[PLACEHOLDER: Resumen de hallazgos principales del análisis ARIMA]

4.2 Implicaciones Prácticas

[PLACEHOLDER: Implicaciones de los pronósticos para inversionistas y analistas de mercado]

4.3 Limitaciones del Análisis

[PLACEHOLDER: Limitaciones del modelo y aspectos no capturados]

4.4 Recomendaciones Futuras

[PLACEHOLDER: Sugerencias para mejoras y extensiones del análisis]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ASIGNATURA: Gestión de Datos
PROFESOR: Orlando Joaqui-Barandica
UNIVERSIDAD: Universidad del Valle
FACULTAD: Facultad de Ingeniería
PROGRAMA: Ingeniería Industrial
ESTUDIANTE: Camilo
FECHA ENTREGA:
VERSIÓN: 1.0
Documento generado con R Markdown | Tema: Series de Tiempo y Pronósticos ARIMA
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━